package com.keywaysoft.workflow.service.impl;

import com.keywaysoft.workflow.constants.WorkflowConstants;
import com.keywaysoft.workflow.dto.*;
import com.keywaysoft.workflow.service.IProcessEngine;
import com.keywaysoft.workflow.utils.*;
import com.keywaysoft.workflow.utils.exception.BizException;
import com.keywaysoft.workflow.vo.ActRuTask;
import com.keywaysoft.workflow.vo.CommentVO;
import com.keywaysoft.workflow.vo.ProcessInstanceVO;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.*;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.util.CollectionUtil;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * Create by zhaojx on 2021/11/21.
 */
@Slf4j
@Service("myProcessEngine")
public class ProcessEngineImpl implements IProcessEngine {

    @Resource
    private RepositoryService repositoryService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private TaskService taskService;

    @Resource
    private HistoryService historyService;


    @Override
    public R start(StartTaskDTO dto) {
        String processKey = dto.getProcessKey();
        String startUserKey = dto.getStartUserKey();
        String businessKey = dto.getBusinessKey();

        Map<String, Object> variables = new HashMap<>();
        final FlowData flowData = new FlowData();

        flowData.setStartUser(startUserKey);
        flowData.setCurrentUser(startUserKey);
        flowData.setFirstNode(true);
        flowData.setFirstSubmit(true);
        flowData.setNextUser(startUserKey);
        variables.put(ProcessKit.FLOW_DATA_KEY, flowData);
        //传入自定义参数
        if (!Objects.isNull(dto.getVariables())) {
            variables.putAll(dto.getVariables());
        }
        variables.put("startUserKey", startUserKey);

        //查询流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processKey).singleResult();
        if (processDefinition.isSuspended()) {
            throw new BizException(WorkflowConstants.FLOW_IS_SUSPENDED);
        }

        ProcessInstance instance = null;
        try {
            //设置流程发起者
            Authentication.setAuthenticatedUserId(String.valueOf(startUserKey));
            //如果有业务key则在流程启动时设置业务key
            if (StringUtils.isNotEmpty(businessKey)) {
                instance = runtimeService.startProcessInstanceByKey(processKey, businessKey, variables);
            } else {
                instance = runtimeService.startProcessInstanceByKey(processKey, variables);
            }
        } catch (Exception e) {
            log.error("根据流程key启动流程,异常:{}", e);
            return R.fail(new BizException(WorkflowConstants.START_FAILURE));
        }
        //指定任务的下一步处理人
        Task nextTask = taskService.createTaskQuery().processInstanceId(instance.getId()).active().singleResult();
        if (StringUtils.isNotBlank(dto.getNextAssigne())) {
            if (nextTask != null) {
                taskService.setAssignee(nextTask.getId(), dto.getNextAssigne());
            }
        }
        if (instance != null) {
            ProcessInstanceVO vo = new ProcessInstanceVO();
            vo.setProcessDefinitionId(instance.getProcessDefinitionId());
            vo.setProcessId(instance.getProcessInstanceId());
            vo.setProcessDefinitionKey(instance.getProcessDefinitionKey());
            vo.setStartUser(instance.getStartUserId());
            vo.setStartTime(instance.getStartTime());
            vo.setBusinessKey(instance.getBusinessKey());
            vo.setIsSuspended(instance.isSuspended());

            flowData.setProcessDefinitionId(instance.getProcessDefinitionId());
            flowData.setProcessInstanceId(instance.getId());
            flowData.setProcessName(instance.getName());
            flowData.setStartUser(instance.getStartUserId());
            flowData.setFirstSubmitTime(instance.getStartTime());
            flowData.setFirstNodeId(nextTask.getTaskDefinitionKey());
            flowData.setCurrentNodeId(nextTask.getTaskDefinitionKey());
            flowData.setCurrentNodeName(nextTask.getName());
            flowData.setTaskId(nextTask.getId());
            flowData.setExecutionId(nextTask.getExecutionId());
            runtimeService.setVariables(instance.getId(), variables);
//            taskService.setVariables(nextTask.getId(), variables);
            return R.success(vo);
        }
        return R.success();
    }

    @Override
    public R searchProcessInstance(String processDefinitionKey) {
        List<ProcessInstance> runningList = new ArrayList<>();
        try {
            ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
            runningList = processInstanceQuery.processDefinitionKey(processDefinitionKey).list();
        } catch (Exception e) {
            log.error("根据流程key查询流程实例,异常:{}", e);
            return R.fail(new BizException(WorkflowConstants.QUERY_FAILURE));
        }

        if (CollectionUtil.isNotEmpty(runningList)) {
            List<Map<String, String>> resultList = new ArrayList<>();
            runningList.forEach(s -> {
                Map<String, String> resultMap = new HashMap<>();
                // 流程实例ID
                resultMap.put("processId", s.getId());
                // 流程定义ID
                resultMap.put("processDefinitionKey", s.getProcessDefinitionId());
                resultList.add(resultMap);
            });
            return R.success(resultList);
        }
        return R.success();
    }

    @Override
    public R updateState(String processInstanceId) {
        ProcessInstance pi = null;
        try {
            pi = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        } catch (Exception e) {
            log.error("根据流程ID查询流程实例,异常:{}", e);
            return R.fail(new BizException(WorkflowConstants.QUERY_FAILURE));
        }
        //获取当前流程实例是否是挂起状态
        boolean suspended = pi.isSuspended();
        if (suspended) {
            runtimeService.activateProcessInstanceById(processInstanceId);
            log.info("已激活ID为[{}]的流程实例。", processInstanceId);
            return R.success().setMsg(WorkflowConstants.FLOW_IS_ACTIVE);
        } else {
            runtimeService.suspendProcessInstanceById(processInstanceId);
            log.info("已挂起ID为[{}]的流程实例。", processInstanceId);
            return R.success().setMsg(WorkflowConstants.FLOW_IS_SUSPEND);
        }
    }

    @Override
    public R searchByID(String processId) {
        ProcessInstance pi = null;
        try {
            pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).includeProcessVariables().singleResult();
        } catch (Exception e) {
            log.error("根据流程ID查询流程实例,异常:{}", e);
            return R.fail(new BizException(WorkflowConstants.QUERY_FAILURE));
        }

        if (pi != null) {
            ProcessInstanceVO vo = new ProcessInstanceVO();
            BeanUtils.copyProperties(pi, vo);
            vo.setVariblesMap(pi.getProcessVariables());
            return R.success(vo);
        }
        return R.success();
    }

    @Override
    public R deleteProcessInstanceByID(String processId) {
        try {
            runtimeService.deleteProcessInstance(processId, "删除" + processId);
            return R.success();
        } catch (Exception e) {
            log.error("根据流程实例ID删除流程实例,异常:{}", e);
            return R.fail(new BizException(WorkflowConstants.DELETE_ERROR));
        }
    }

    @Override
    public R deleteProcessInstanceByKey(String processDefinitionKey) {
        List<ProcessInstance> runningList = new ArrayList<>();
        try {
            ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
            runningList = processInstanceQuery.processDefinitionKey(processDefinitionKey).list();
        } catch (Exception e) {
            log.error("根据流程实例key删除流程实例,异常:{}", e);
            return R.fail(new BizException(WorkflowConstants.BACK_ERROR));
        }

        if (CollectionUtil.isNotEmpty(runningList)) {
            List<Map<String, String>> resultList = new ArrayList<>();
            runningList.forEach(s -> runtimeService.deleteProcessInstance(s.getId(), "删除"));
            return R.success(resultList);
        }
        return R.success();
    }


    @Override
    public void withdrawApproval(TaskBaseDTO dto) {
        String oldTaskId = dto.getTaskId();
        String userKey = dto.getUserKey();
        HistoricTaskInstance historicTaskInstance = ProcessKit.getHistoricTaskInstance(oldTaskId);
        // 目标跳转节点
        final String targetNodeId = historicTaskInstance.getTaskDefinitionKey();
        final String processDefinitionId = historicTaskInstance.getProcessDefinitionId();
        final String processInstanceId = historicTaskInstance.getProcessInstanceId();

        if (ProcessKit.isFinished(processInstanceId)) {
            throw new BizException(WorkflowConstants.WITH_DRAW_APPROVAL_END_ERROR);
        }

        // 判断节点是否已被提交，如已提交则不能撤回
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        if (tasks.size() == 1) {
            Task currentTask = tasks.get(0);
            String currentTaskId = currentTask.getId();
            String currentNodeId = currentTask.getTaskDefinitionKey();

            final Map<String, Object> variables = taskService.getVariables(currentTaskId);

            // 计算期望节点ID
            List<UserTask> nextNodes = ProcessKit.getNextNode(processDefinitionId, targetNodeId, variables);
            if (nextNodes.size() > 1) {
                throw new BizException(WorkflowConstants.WITH_DRAW_APPROVAL_ERROR);
            }
            UserTask userTask = nextNodes.get(0);
            String expectNodeId = userTask.getId();
            if (currentNodeId.equals(expectNodeId)) {
                // 撤回
                ProcessKit.setNextUser(userKey, variables);
                ProcessKit.nodeJumpTo(currentTaskId, targetNodeId, variables, "撤回");
            } else {
                throw new BizException(WorkflowConstants.WITH_DRAW_APPROVAL_ERROR);
            }

        } else if (tasks.size() > 1) {
            throw new BizException(WorkflowConstants.WITH_DRAW_APPROVAL_MORE_ERROR);
        } else {
            throw new BizException(WorkflowConstants.WITH_DRAW_APPROVAL_ERROR);
        }

    }

    @Override
    public R<Map<String, Object>> getCurrentUserTaskVariables(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (Objects.isNull(task)) {
            return R.fail(new BizException(WorkflowConstants.NO_TASK));
        }
        return R.success(taskService.getVariables(taskId));
    }

    @Override
    public R<List<CommentVO>> getProcessInstanceComments(String processInstanceId) {
        List<Comment> comments = taskService.getProcessInstanceComments(processInstanceId, "comment");
        ArrayList<CommentVO> commentVOS = new ArrayList<>();
        for (int i = comments.size() - 1; i >= 0; i--) {
            CommentVO commentVO = new CommentVO();
            Comment comment = comments.get(i);
            BeanUtils.copyProperties(comment, commentVO);
            HistoricTaskInstance historicTaskInstance = ProcessKit.getHistoricTaskInstance(comment.getTaskId());
            commentVO.setAssigne(historicTaskInstance.getAssignee());
            commentVO.setTaskName(historicTaskInstance.getName());
            commentVOS.add(commentVO);
        }
        return R.success(commentVOS);
    }


    @Override
    public void backToFirstNode(BackTaskDTO dto) {
        String taskId = dto.getTaskId();
        String userkey = dto.getUserKey();
        String comment = dto.getComment();
        Map<String, Object> variables = taskService.getVariables(taskId);
        FlowData flowData = ProcessKit.getFlowData(variables);
        flowData.setFirstNode(true);
        flowData.setNextUser(flowData.getStartUser());
        ProcessKit.nodeJumpTo(taskId, flowData.getFirstNodeId(), userkey, variables, comment);
    }

    @Override
    public R getNodeList(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (Objects.isNull(task)) {
            return R.fail(WorkflowConstants.NO_TASK);
        }
        List<ProcessNode> canBackNodes = ProcessKit.getCanBackNodes(task.getTaskDefinitionKey(), task.getProcessDefinitionId());
        return R.success(canBackNodes);
    }

    @Override
    public void backToPreNode(BackTaskDTO dto) {
        String taskId = dto.getTaskId();
        String userkey = dto.getUserKey();
        String comment = dto.getComment();
        Map<String, Object> variables = taskService.getVariables(taskId);
        FlowData flowData = ProcessKit.getFlowData(variables);
        Task currentTask = ProcessKit.getCurrentTask(taskId);
        // 获取上一环节
        ProcessNode preOneIncomeNode = ProcessKit.getPreOneIncomeNode(currentTask.getTaskDefinitionKey(), flowData.getProcessDefinitionId());
        if (preOneIncomeNode == null) {
            throw new BizException(WorkflowConstants.BACK_ERROR);
        }
        String preNodeId = preOneIncomeNode.getNodeId();
        // 设置下一节点审批人
        setNextUser(flowData, preNodeId);
        //驳回
        ProcessKit.nodeJumpTo(taskId, preNodeId, userkey, variables, comment);
    }

    /**
     * 设置下一节点审批人
     *
     * @param flowData
     * @param preNodeId
     */
    private void setNextUser(FlowData flowData, String preNodeId) {
        // 如果是首环节
        if (preNodeId.equals(flowData.getFirstNodeId())) {
            flowData.setFirstNode(true);
            flowData.setNextUser(flowData.getStartUser());
        } else {
            // 获取目标节点审批人
            int taskType = ProcessKit.getTaskType(preNodeId, flowData.getProcessDefinitionId());
            if (taskType == ProcessKit.USER_TASK_TYPE_NORMAL) {
                HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery()
                        .processInstanceId(flowData.getProcessInstanceId()).activityId(preNodeId).finished().singleResult();
                String assignee = historicActivityInstance.getAssignee();
                flowData.setNextUser(assignee);
            } else {
                throw new BizException(WorkflowConstants.NO_APPLY_MORE_INSTANCE_ERROR);
            }
        }
    }

    @Override
    public void back2Node(TargetBackTaskDTO dto) {
        String comment = dto.getComment();
        String targetNodeId = dto.getTargetNodeId();
        Map<String, Object> variables = taskService.getVariables(dto.getTaskId());
        FlowData flowData = ProcessKit.getFlowData(variables);
        // 设置下一节点审批人
        setNextUser(flowData, targetNodeId);
        if (StringUtils.isEmpty(comment)) {
            FlowElement flowElement = ProcessKit.getFlowElement(targetNodeId, flowData.getProcessDefinitionId());
            String commentStr = "驳回至【" + flowElement.getName() + "】环节";
            dto.setComment(commentStr);
        }
        ProcessKit.nodeJumpTo(dto.getTaskId(), targetNodeId, dto.getUserKey(), variables, comment);
    }

    /**
     * 结束任务
     */
    @Override
    public void endTask(BackTaskDTO dto) {
        String taskId = dto.getTaskId();
        String userKey = dto.getUserKey();
        String comment = dto.getComment();
        //  当前任务
        Task task = taskService.createTaskQuery().taskAssignee(userKey).taskId(taskId).singleResult();
        if (Objects.isNull(task)) {
            throw new BizException(WorkflowConstants.NO_TASK);
        }

        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        List endEventList = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class);
        //获取结束节点
        FlowNode endFlowNode = (FlowNode) endEventList.get(0);
        //获取当前节点
        FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());

        //  临时保存当前活动的原始方向
        List originalSequenceFlowList = new ArrayList<>();
        originalSequenceFlowList.addAll(currentFlowNode.getOutgoingFlows());
        //  清理活动方向
        currentFlowNode.getOutgoingFlows().clear();

        //  建立新方向
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId");
        newSequenceFlow.setSourceFlowElement(currentFlowNode);
        newSequenceFlow.setTargetFlowElement(endFlowNode);
        List newSequenceFlowList = new ArrayList<>();
        newSequenceFlowList.add(newSequenceFlow);
        //  当前节点指向新的方向
        currentFlowNode.setOutgoingFlows(newSequenceFlowList);
        //添加审批意见
        taskService.addComment(taskId, task.getProcessInstanceId(), comment);
        //  完成当前任务
        taskService.complete(task.getId());

        //  可以不用恢复原始方向，不影响其它的流程
        //恢复原始方向
        currentFlowNode.setOutgoingFlows(originalSequenceFlowList);
    }

    @Override
    public R<Page<ActRuTask>> taskQuery(FindTaskByAssigneeDTO dto) {
        Integer isGetParam = dto.getIsGetParam();
        String key = dto.getKey();
        List<Task> list = new ArrayList<>();
        Page<ActRuTask> objectPage = null;
        try {
            TaskQuery taskQuery = taskService.createTaskQuery().orderByTaskCreateTime().desc();
            if (StringUtils.isNotBlank(key)) {
                taskQuery.taskDefinitionKey(key);
            }
            //isGetParam==1需要查询自定义参数
            if (null != isGetParam && 1 == isGetParam) {
                //查询自定义参数
                taskQuery.includeProcessVariables();
            }

            //分页查询
            objectPage = new Page<>(dto.getPageNum(), dto.getPageSize());
            objectPage.setCount(taskQuery.count());
            list.addAll(taskQuery.listPage(objectPage.getFirstResult(), objectPage.getLastResult()));
        } catch (Exception e) {
            return R.fail(new BizException(e.getMessage()));
        }

        objectPage.setList(getActRuTaskList(list));
        return R.success(objectPage);
    }

    /**
     * 封装任务列表的返回值
     *
     * @param list
     * @return
     */
    private List<ActRuTask> getActRuTaskList(List<Task> list) {
        List<ActRuTask> actRuTasks = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                //封装返回结果
                ActRuTask actRuTask = new ActRuTask();
                actRuTask.setId(task.getId());
                actRuTask.setName(task.getName());
                actRuTask.setAssignee(task.getAssignee());
                actRuTask.setCreateTime(task.getCreateTime());
                actRuTask.setProcInstId(task.getProcessInstanceId());
                actRuTask.setExecutionId(task.getExecutionId());
                actRuTask.setProcDefId(task.getProcessDefinitionId());
                actRuTask.setTaskDefKey(task.getTaskDefinitionKey());
                actRuTask.setVariblesMap(task.getProcessVariables());
                actRuTask.setParentTaskId(task.getParentTaskId());

                //查询流程实例信息
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                actRuTask.setBusinessKey(processInstance.getBusinessKey());
                actRuTask.setDeploymentId(processInstance.getDeploymentId());
                actRuTask.setDefinitionKey(processInstance.getProcessDefinitionKey());

                actRuTasks.add(actRuTask);
            }
        }
        return actRuTasks;
    }


    @Override
    public R<Page<ActRuTask>> findTaskByAssignee(FindTaskByAssigneeDTO dto) {
        List<String> usersGroups = new ArrayList<>();
        try {
            if (StringUtils.isNotEmpty(dto.getGroups())) {
                usersGroups.addAll(ListUtil.strToList(dto.getGroups()));
            }
            TaskQuery taskQuery = taskService.createTaskQuery().active().orderByTaskCreateTime().desc();
            //封装候选人或者候选组
            if (usersGroups.size() > 0) {
                taskQuery.taskCandidateGroupIn(usersGroups);
            } else {
                taskQuery.taskCandidateOrAssigned(dto.getAssignee());
            }

            if (StringUtils.isNotBlank(dto.getKey())) {
                taskQuery.processDefinitionKey(dto.getKey());
            }
            //isGetParam==1需要查询自定义参数
            if (1 == dto.getIsGetParam()) {
                //查询自定义参数
                taskQuery.includeProcessVariables();
            }

            //分页查询
            Page page = new Page(dto.getPageNum(), dto.getPageSize(), taskQuery.count());
            List<Task> taskList = taskQuery.listPage(page.getFirstResult(), page.getLastResult());

            //组装返回值参数
            page.setList(getActRuTaskList(taskList));
            return R.success(page);
        } catch (Exception e) {
            log.error("根据流程assignee查询当前人的个人任务,异常:{}", e);
            return R.fail(WorkflowConstants.QUERY_FAILURE, e.getMessage());
        }
    }


    @Override
    public R completeTask(CompleteTaskDTO dto) {
        try {
            // 若是委托任务，请先解决委托任务
            Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
            if (Objects.isNull(task)) {
                return R.fail(new BizException(WorkflowConstants.NO_TASK));
            }
            if (DelegationState.PENDING.equals(task.getDelegationState())) {
                return R.fail(new BizException(WorkflowConstants.PENDING));
            }
            if (task.isSuspended()) {
                return R.fail(WorkflowConstants.IS_SUSPENDED);
            }
            Map<String, Object> variables = taskService.getVariables(task.getId());

            //如果当前用户不是审批人则先签收任务（此时说明是组任务，需要先签收）
            if (!dto.getUserKey().equals(task.getAssignee())) {
                taskService.claim(dto.getTaskId(), dto.getUserKey());
            }
            //添加审批意见
            taskService.addComment(task.getId(), task.getProcessInstanceId(), dto.getComment());

            FlowData flowData = ProcessKit.getFlowData(variables);
            if (flowData.isFirstSubmit()) {
                flowData.setFirstSubmitTime(new Date());
            }
            flowData.setFirstNode(false);
            flowData.setFirstSubmit(false);
            flowData.setCurrentNodeId(task.getTaskDefinitionKey());
            // 记录每个实例任务节点审批人
            HashMap<String, NodeAssignee> nodeAssignee = flowData.getNodeAssignee();
            if (nodeAssignee == null) {
                nodeAssignee = new HashMap<>();
            }
            final String currentNodeId = task.getTaskDefinitionKey();
            String taskId = task.getId();
            nodeAssignee.put(currentNodeId + ProcessKit.FLOW_SPLIT + taskId, new NodeAssignee(taskId, currentNodeId, dto.getUserKey()));
            flowData.setNodeAssignee(nodeAssignee);
            variables.put(ProcessKit.FLOW_DATA_KEY, flowData);

            if (Objects.nonNull(dto.getVariables())) {
                variables.putAll(dto.getVariables());
            }
            //完成任务
            taskService.complete(dto.getTaskId(), variables);

            //指定任务的下一步处理人
            if (StringUtils.isNotBlank(dto.getNextAssigne())) {
                Task nextTask = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).active().singleResult();
                if (nextTask != null) {
                    taskService.setAssignee(nextTask.getId(), dto.getNextAssigne());
                }
            }
            return R.success(dto.getTaskId());
        } catch (Exception e) {
            log.error("完成任务,异常:{}", e);
            return R.fail(new BizException(e.getMessage()));
        }
    }

    @Override
    public R turnTask(TaskBaseDTO dto) {
        String taskId = dto.getTaskId();
        String userKey = dto.getUserKey();
        try {
            //查询任务
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (Objects.isNull(task)) {
                return R.fail(new BizException(WorkflowConstants.NO_TASK));
            }
            taskService.setAssignee(taskId, userKey);
            return R.success(taskId);
        } catch (Exception e) {
            log.error("任务转办,异常:{}", e);
            return R.fail(new BizException(e.getMessage()));
        }
    }

    @Override
    public R claim(TaskBaseDTO dto) {
        String taskId = dto.getTaskId();
        String userKey = dto.getUserKey();
        boolean isClaim = false;
        if (StringUtils.isBlank(taskId) || StringUtils.isBlank(userKey)) {
            throw new BizException(WorkflowConstants.PARAM_ERROR);
        }
        //        查询任务
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskCandidateUser(userKey)
                .singleResult();
        if (task != null) {
            isClaim = true;
//            拾取任务
            taskService.claim(taskId, userKey);
            log.info("任务 taskid={} 被用户:{} 拾取完成", taskId, userKey);
        }
        return R.success(isClaim);
    }


    @Override
    public R unclaim(TaskBaseDTO dto) {
        String taskId = dto.getTaskId();
        String userId = dto.getUserKey();
        boolean isClaim = false;
        if (StringUtils.isEmpty(taskId) || StringUtils.isEmpty(userId)) {
            throw new BizException(WorkflowConstants.PARAM_ERROR);
        }
        //        查询任务
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .taskCandidateUser(userId)
                .singleResult();
        if (task != null) {
            isClaim = true;
//            放弃任务
            taskService.unclaim(taskId);
            log.info("任务 taskid={} 被用户:{} 放弃签收", taskId, userId);
        }
        return R.success(isClaim);
    }


    @Override
    public R delegateTask(TaskBaseDTO dto) {
        taskService.delegateTask(dto.getTaskId(), dto.getUserKey());
        return R.success();
    }

    @Override
    public R resolveTask(TaskDTO dto) {
        String taskId = dto.getTaskId();
        Map<String, Object> variables = dto.getVariables();
        // 设置流程参数（多）
        taskService.setVariables(taskId, variables);
        // 根据taskId提取任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task.getOwner() != null && !"null".equals(task.getOwner())) {
            DelegationState delegationState = task.getDelegationState();
            if (delegationState.equals(DelegationState.RESOLVED)) {
                return R.success(new BizException(WorkflowConstants.TASK_IS_END));
            } else if (delegationState.equals(DelegationState.PENDING)) {
                // 如果是委托任务需要做处理
                taskService.resolveTask(taskId, variables);
            } else {
                return R.fail(new BizException(WorkflowConstants.NOT_RESOLVE));
            }
        }
        return R.success();
    }
}
